package com.jctrip.hotel.source.service.rezen.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.jctrip.hotel.domain.dao.HtSourceInfoDao;
import com.jctrip.hotel.domain.entity.HtPriceCalendarRezen;
import com.jctrip.hotel.domain.entity.HtSourceInfo;
import com.jctrip.hotel.source.model.rezen.req.*;
import com.jctrip.hotel.source.model.rezen.resp.*;
import com.jctrip.hotel.source.service.HotelCommonTaskService;
import com.jctrip.hotel.source.service.basic.HtPriceCalendarRezenService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jctrip.hotel.common.enums.OrderStatusEnum;
import com.jctrip.hotel.common.enums.SourceEnum;
import com.jctrip.hotel.common.util.JsonUtil;
import com.jctrip.hotel.common.util.PriceUtil;
import com.jctrip.hotel.source.client.RezenClient;
import com.jctrip.hotel.source.model.OrderDataResult;
import com.jctrip.hotel.source.model.PriceCheckParam;
import com.jctrip.hotel.source.model.rezen.req.RezenCancelOrderReq.ReservationIds;
import com.jctrip.hotel.source.model.rezen.req.RezenPostOrderReq.DailyRateList;
import com.jctrip.hotel.source.model.rezen.resp.CityInfoDTO.CityInfoData;
import com.jctrip.hotel.source.model.rezen.resp.ProductListDTO.ProductList;
import com.jctrip.hotel.source.model.rezen.resp.ProductListDTO.RoomPriceList;
import com.jctrip.hotel.source.model.rezen.resp.ProductListDTO.RoomTypeList;
import com.jctrip.hotel.source.model.rezen.resp.QueryOrderStatusDTO.OrderStatusData;
import com.jctrip.hotel.source.model.rezen.resp.RoomTypeDTO.RoomType;
import com.jctrip.hotel.source.model.wehotel.req.OrderData;
import com.jctrip.hotel.source.service.rezen.RezenService;
import com.jctrip.hotel.source.service.rezen.RezenSigUtils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

/**
 * @Author henry
 * @Date 2023/8/12 10:57
 * @Description
 */
@Service
@Slf4j
public class RezenServiceImpl implements RezenService {

    @Resource
    private RezenClient rezenClient;

    @Resource
    private HtSourceInfoDao htSourceInfoDao;

    @Resource
    private HtPriceCalendarRezenService htPriceCalendarRezenService;

    @Autowired
    private HotelCommonTaskService hotelCommonTaskService;

    @Override
    public Long parseHotelId(String innId) {
        if (StringUtils.isBlank(innId)) {
            return null;
        }
        return Long.valueOf(innId.substring(SourceEnum.REZEN.getCode().length()));
    }

    @Override
    public String parseInnId(Long hotelId) {
        if (null == hotelId) {
            return null;
        }
        return SourceEnum.REZEN.getCode() + hotelId;
    }

    @Override
    public Long parseHotelId3(String innId) {
        if (StringUtils.isBlank(innId)) {
            return null;
        }
        return Long.valueOf(innId.substring(SourceEnum.REZENCO.getCode().length()));
    }

    @Override
    public String parseInnId3(Long hotelId) {
        if (null == hotelId) {
            return null;
        }
        return SourceEnum.REZENCO.getCode() + hotelId;
    }

    // 判断sourceId是否为二方。
    @Override
    public Boolean checkSourceIdIs2(String sourceId) {
        // 36697437二方sourceId
        if ("36697437".equals(sourceId)) {
            return true;
        }
        return false;
    }

    @Override
    public List<CityInfoData> getCity(String secretId, String secretKey, Long groupId) {
        RezenQueryCityReq req = RezenQueryCityReq.builder().groupId(groupId).build();
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<List<CityInfoDTO>> resp = rezenClient.getCityList(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        List<CityInfoData> result = new ArrayList<>();
        Optional.ofNullable(resp.getBody()).orElse(new ArrayList<>()).forEach(data -> {
            result.addAll(data.getHotelList());
        });
        return result;
    }

    @Override
    public List<HotelInfoDTO> queryHotelList(String secretId, String secretKey, Long groupId, String cityCode) {
        QueryHotelReq req = QueryHotelReq.builder().groupId(groupId).cityCode(cityCode).build();
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<List<HotelInfoDTO>> resp =
                rezenClient.queryHotelList(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp.getBody();
    }

    @Override
    public List<RoomType> queryRoomType(String secretId, String secretKey, Long groupId, Long hotelId) {
        ProductBriefListReq req = ProductBriefListReq.builder().hotelId(hotelId).groupId(groupId).build();
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<RoomTypeDTO> resp = rezenClient.getRoomType(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return Optional.ofNullable(resp.getBody()).map(RoomTypeDTO::getRoomTypeList).orElse(new ArrayList<>());
    }

    @Override
    public ProductListDTO getRoomStatus(String secretId, String secretKey, Long groupId, Long hotelId,
                                        String roomTypeId, String start, String end) {
        QueryProductListReq req =
                QueryProductListReq.builder()
                        .groupId(groupId)
                        .hotelId(hotelId)
                        .checkInDate(start)
                        .checkOutDate(end)
                        .build();
        if (StringUtils.isNotBlank(roomTypeId)) {
            req.setRoomTypeIdList(Collections.singletonList(Long.valueOf(roomTypeId)));
        }
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<ProductListDTO> resp = rezenClient.getProductList(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp.getBody();
    }

    @Override
    public RezenBaseResp<RezenOrderResp> reserveOrder(String secretId, String secretKey, RezenPostOrderReq req) {
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<RezenOrderResp> resp = rezenClient.reserveOrder(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp;
    }

    @Override
    public OrderDataResult postOrder(String secretId, String secretKey, RezenPostOrderReq req,
                                     PriceCheckParam priceCheck) {
        // 查询房态
        ProductListDTO roomStatus =
                getRoomStatus(secretId, secretKey, req.getGroupId(), req.getHotelId(),
                        String.valueOf(req.getRoomRate().getRoomtypId()),
                        req.getCheckInDate(), req.getCheckOutDate());
        ProductList product =
                Optional.ofNullable(roomStatus).map(ProductListDTO::getRoomTypeList).orElse(new ArrayList<>()).stream()
                        .filter(roomType -> roomType.getRoomtypId().equals(req.getRoomRate().getRoomtypId()))
                        .findFirst().map(RoomTypeList::getProductList).orElse(new ArrayList<>()).stream()
                        .filter(productList -> productList.getProductId().equals(req.getRoomRate().getProductId()))
                        .findAny().orElse(null);
        if (Objects.isNull(product)) {
            hotelCommonTaskService.insertOrderErrorLog(req.getDistributorResId(), JsonUtil.toString(req),
                    String.format("下单失败，没有获取到对饮该产品product id:%s的房态信息",
                            req.getRoomRate().getProductId()));
            throw new RuntimeException(String.format("下单失败，没有获取到对饮该产品product id:%s的房态信息",
                    req.getRoomRate().getProductId()));
        }

        //价格日历
        List<DailyRateList> dailyRateLists = new ArrayList<>();
        BigDecimal totalPrice = BigDecimal.ZERO;
        BigDecimal raisedTotalPrice = BigDecimal.valueOf(0);
        for (RoomPriceList roomPriceList : product.getRoomPriceList()) {
            DailyRateList dailyRate =
                    DailyRateList.builder().effectDate(roomPriceList.getDay()).roomPrice(roomPriceList.getPrice())
                            .build();
            dailyRateLists.add(dailyRate);
            totalPrice = totalPrice.add(BigDecimal.valueOf((long) roomPriceList.getPrice() * req.getRoomQuantity()));
            raisedTotalPrice =
                    raisedTotalPrice.add(priceCheck.getRaiseFunc()
                            .apply(PriceUtil.fen2yuan(roomPriceList.getPrice())));
        }

        if (priceCheck.getTotalRate().compareTo(raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity()))
                .subtract(priceCheck.getTolerancePrice())) < 0) {
            String error = String.format("订单销售价不能低于采购总价，订单销售价=%s，采购总价=%s, 容差金额=%s, 目前差额=%s",
                    priceCheck.getTotalRate(),
                    raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity())),
                    priceCheck.getTolerancePrice(),
                    raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity())).subtract(priceCheck.getTotalRate()));
            hotelCommonTaskService.insertOrderErrorLog(req.getDistributorResId(), JsonUtil.toString(req), error);
            log.error("订单销售价不能低于采购总价，订单销售价={}，采购总价={}, 容差金额={}, 目前差额={}",
                    priceCheck.getTotalRate(), raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity())),
                    priceCheck.getTolerancePrice(), raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity())).subtract(priceCheck.getTotalRate()));
            throw new RuntimeException("订单销售价不能低于采购总价");
        }

        req.getRoomRate().setDailyRateList(dailyRateLists);
        req.setTotalAmount(totalPrice.intValue());
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<RezenOrderResp> resp = rezenClient.reserveOrder(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            hotelCommonTaskService.insertOrderErrorLog(req.getDistributorResId(), JsonUtil.toString(req), resp.getRetdesc());
            throw new RuntimeException(resp.getRetdesc());
        }
        return OrderDataResult.builder().orderCode(String.valueOf(resp.getBody().getCrsOrderNo()))
                .externalId(req.getDistributorResId()).totalRate(PriceUtil.fen2yuan(totalPrice.intValue())).orderState(
                        OrderStatusEnum.BOOK_SUCCESS.getCode()).requestJsonStr(JsonUtil.toString(req))
                .responseJsonStr(JsonUtil.toString(req)).build();
    }

    @Override
    public OrderDataResult postOrderByCompany(String secretId, String secretKey, RezenPostOrderReq req,
                                              PriceCheckParam priceCheck) {
        // 查询房态
        ProductListByCompanyIdReq productListByCompanyIdReq = ProductListByCompanyIdReq.builder()
                .hotelId(req.getHotelId())
                .groupId(req.getGroupId())
                .checkInDate(req.getCheckInDate())
                .checkOutDate(req.getCheckOutDate())
                .companyIdList(Lists.newArrayList(req.getCompanyId()))
                .roomQuantity(req.getRoomQuantity())
                .roomTypeIdList(Lists.newArrayList(req.getRoomRate().getRoomtypId()))
                .build();
        List<ProductListByCompanyIdResp> roomStatusList = getRoomStatusByCompanyId(productListByCompanyIdReq, secretId, secretKey);
        if (CollectionUtils.isEmpty(roomStatusList)) {
            hotelCommonTaskService.insertOrderErrorLog(req.getDistributorResId(), JsonUtil.toString(req),
                    String.format("下单失败，没有获取到对饮该产品product id:%s的房态信息",
                            req.getRoomRate().getProductId()));
            throw new RuntimeException(String.format("下单失败，没有获取到对饮该产品product id:%s的房态信息",
                    req.getRoomRate().getProductId()));
        }
        ProductListByCompanyIdResp roomStatus = roomStatusList.get(0);
        ProductListByCompanyIdResp.RoomTypeListBean.ProductListBean product =
                Optional.ofNullable(roomStatus).map(ProductListByCompanyIdResp::getRoomTypeList).orElse(new ArrayList<>()).stream()
                        .filter(roomType -> roomType.getRoomtypId().equals(req.getRoomRate().getRoomtypId()))
                        .findFirst().map(ProductListByCompanyIdResp.RoomTypeListBean::getProductList).orElse(new ArrayList<>()).stream()
                        .filter(productList -> productList.getProductId().equals(req.getRoomRate().getProductId()))
                        .findAny().orElse(null);

        if (Objects.isNull(product)) {
            hotelCommonTaskService.insertOrderErrorLog(req.getDistributorResId(), JsonUtil.toString(req),
                    String.format("下单失败，没有获取到对饮该产品product id:%s的房态信息",
                            req.getRoomRate().getProductId()));
            throw new RuntimeException(String.format("下单失败，没有获取到对饮该产品product id:%s的房态信息",
                    req.getRoomRate().getProductId()));
        }

        //价格日历
        List<DailyRateList> dailyRateLists = new ArrayList<>();
        BigDecimal totalPrice = BigDecimal.ZERO;
        BigDecimal raisedTotalPrice = BigDecimal.valueOf(0);
        for (ProductListByCompanyIdResp.RoomTypeListBean.ProductListBean.RoomPriceListBean roomPriceList : product.getRoomPriceList()) {
            DailyRateList dailyRate =
                    DailyRateList.builder().effectDate(roomPriceList.getDay()).roomPrice(roomPriceList.getPrice())
                            .build();
            dailyRateLists.add(dailyRate);
            totalPrice = totalPrice.add(BigDecimal.valueOf((long) roomPriceList.getPrice() * req.getRoomQuantity()));
            raisedTotalPrice =
                    raisedTotalPrice.add(priceCheck.getRaiseFunc()
                            .apply(PriceUtil.fen2yuan(roomPriceList.getPrice())));
        }

        if (priceCheck.getTotalRate().compareTo(raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity()))
                .subtract(priceCheck.getTolerancePrice())) < 0) {
            String error = String.format("订单销售价不能低于采购总价，订单销售价=%s，采购总价=%s, 容差金额=%s, 目前差额=%s",
                    priceCheck.getTotalRate(),
                    raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity())),
                    priceCheck.getTolerancePrice(),
                    raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity())).subtract(priceCheck.getTotalRate()));
            hotelCommonTaskService.insertOrderErrorLog(req.getDistributorResId(), JsonUtil.toString(req), error);
            log.error("订单销售价不能低于采购总价，订单销售价={}，采购总价={}, 容差金额={}, 目前差额={}",
                    priceCheck.getTotalRate(), raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity())),
                    priceCheck.getTolerancePrice(), raisedTotalPrice.multiply(BigDecimal.valueOf(req.getRoomQuantity())).subtract(priceCheck.getTotalRate()));
            throw new RuntimeException("订单销售价不能低于采购总价");
        }

        req.getRoomRate().setDailyRateList(dailyRateLists);
        req.setTotalAmount(totalPrice.intValue());
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<RezenOrderResp> resp = rezenClient.reserveOrder(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            hotelCommonTaskService.insertOrderErrorLog(req.getDistributorResId(), JsonUtil.toString(req), resp.getRetdesc());
            throw new RuntimeException(resp.getRetdesc());
        }
        return OrderDataResult.builder().orderCode(String.valueOf(resp.getBody().getCrsOrderNo()))
                .externalId(req.getDistributorResId()).totalRate(PriceUtil.fen2yuan(totalPrice.intValue())).orderState(
                        OrderStatusEnum.BOOK_SUCCESS.getCode()).requestJsonStr(JsonUtil.toString(req))
                .responseJsonStr(JsonUtil.toString(req)).build();
    }
    @Override
    public OrderData getOrderStatus(String secretId, String secretKey, Long groupId, String outOrderId) {
        Long timestamp = new Date().getTime();
        RezenQuerOrderReq req = RezenQuerOrderReq.builder()
                .distributorResIds(Collections.singletonList(outOrderId))
                .groupId(groupId)
                .requestId(String.valueOf(timestamp))
                .build();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<QueryOrderStatusDTO> resp = rezenClient.queryOrderStatus(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        OrderStatusData orderStatusData =
                Optional.ofNullable(resp.getBody()).map(QueryOrderStatusDTO::getPullOrderStatusItemList)
                        .orElse(new ArrayList<>()).stream()
                        .filter(item -> item.getDistributorResId().equals(outOrderId))
                        .findFirst().orElse(null);
        if (orderStatusData == null) {
            throw new RuntimeException("订单查询失败");
        }

        Integer orderState = orderStatusData.getCrsOrderNo() == -1 ? 6 : 1;
        OrderData orderData = new OrderData();
        // orderState 不为6
        if (StringUtils.isNotBlank(orderStatusData.getOrderStatus()) && orderState != 6) {
            switch (orderStatusData.getOrderStatus()) {
                case "N":
                    orderState = 0;
                    break;
                case "A":
                    orderState = 1;
                    break;
                case "NS":
                    orderState = 3;
                    break;
                case "C":
                    orderState = 4;
                    break;
                case "F":
                    orderState = 5;
                    break;
                case "E":
                    orderState = 2;
                    break;
                default:
                    break;
            }
        }
        orderData.setOrderCode(
                orderStatusData.getCrsOrderNo() == null ? null : String.valueOf(orderStatusData.getCrsOrderNo()));
        orderData.setOrderState(orderState);
        orderData.setExternalId(outOrderId);
        return orderData;
    }

    @Override
    public Boolean cancelOrder(String secretId, String secretKey, Long groupId, Long orderId, String outOrderId) {
        RezenCancelOrderReq req = RezenCancelOrderReq.builder().groupId(groupId)
                .reservationIds(ReservationIds.builder().crsOrderNo(orderId).distributorResId(outOrderId).build())
                .build();
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<RezenCancelOrderDTO> resp =
                rezenClient.cancelOrder(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return Boolean.TRUE;
    }

    @Override
    public RezenPullOrderInhotelInfoResp pullOrderInhotelInfo(String sourceId, RezenPullOrderInhotelInfoReq req) {
        if (CollectionUtils.isEmpty(req.getDistributorResIds())) {
            throw new RuntimeException("订单号为空");
        }
        HtSourceInfo htSourceInfo =
                htSourceInfoDao.selectOne(new LambdaQueryWrapper<HtSourceInfo>().eq(HtSourceInfo::getSourceId,
                        sourceId));
        if (htSourceInfo == null) {
            throw new RuntimeException("供应商账户为空");
        }
        String secretId = htSourceInfo.getSourceAppId();
        String secretKey = htSourceInfo.getSourceSecret();

        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<RezenPullOrderInhotelInfoResp> resp = rezenClient.pullOrderInhotelInfo(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp.getBody();
    }

    @Override
    public String getProductId(String hotelId, String roomTypeCode, String sourceId, Integer breakfast, Integer cancelType, String calDate) {
        // 先还原酒店id
        Long preHotelId = null;
        if (hotelId.startsWith("REZENCO")) {
            preHotelId = parseHotelId3(hotelId);
        } else {
            preHotelId = parseHotelId(hotelId);
        }

        // 根据二方或者三方 ，添加前缀
        if (checkSourceIdIs2(sourceId)) {
            //二方
            hotelId = parseInnId(preHotelId);
        } else {
            // 三方
            hotelId = parseInnId3(preHotelId);
        }
        return Optional.ofNullable(htPriceCalendarRezenService.getOne(new LambdaQueryWrapper<HtPriceCalendarRezen>()
                        .eq(HtPriceCalendarRezen::getHotelId, hotelId)
                        .eq(HtPriceCalendarRezen::getRoomTypeCode, roomTypeCode)
                        .eq(HtPriceCalendarRezen::getCalDate, calDate)
                        .eq(HtPriceCalendarRezen::getSourceId, sourceId)
                        .eq(HtPriceCalendarRezen::getBreakfastCount, breakfast)
                        .eq(HtPriceCalendarRezen::getCancelPolicyType, cancelType)
                        .select(HtPriceCalendarRezen::getProductId))).orElse(new HtPriceCalendarRezen())
                .getProductId();
    }

    @Override
    public List<HotelInfoIdDTO> queryHotelList2(String secretId, String secretKey, Long groupId) {
        HotelListReq req = HotelListReq.builder().groupId(groupId).build();
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<List<HotelInfoIdDTO>> resp =
                rezenClient.queryHotelList2(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp.getBody();
    }

    @Override
    public List<HotelInfoIdDTO> queryHotelListForCompany(String secretId, String secretKey, Long groupId) {
        HotelListReq req = HotelListReq.builder().groupId(groupId).build();
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<List<HotelInfoIdDTO>> resp =
                rezenClient.queryHotelListForCompany(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp.getBody();
    }

    @Override
    public HotelDetailsResp queryHotelDetails(HotelDetailsReq req, String secretId, String secretKey) {
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<HotelDetailsResp> resp =
                rezenClient.queryHotelDetails(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp.getBody();
    }

    @Override
    public List<GetCompanyListResp> getCompanyList(HotelListReq req, String secretId, String secretKey) {
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<List<GetCompanyListResp>> resp =
                rezenClient.getCompanyList(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp.getBody();

    }

    @Override
    public List<ProductBriefListByCompanyIdResp> queryRoomTypeByCompanyId(ProductBriefListByCompanyIdReq req, String secretId, String secretKey) {
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<List<ProductBriefListByCompanyIdResp>> resp =
                rezenClient.getRoomTypeByCompanyId(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp.getBody();
    }

    @Override
    public List<ProductListByCompanyIdResp> getRoomStatusByCompanyId(ProductListByCompanyIdReq req, String secretId, String secretKey) {
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<List<ProductListByCompanyIdResp>> resp =
                rezenClient.getProductListByCompanyId(req, secretId, timestamp, sign);
        if (resp.isFail()) {
            throw new RuntimeException(resp.getRetdesc());
        }
        return resp.getBody();
    }

    @Override
    public RezenBaseResp<List<PostOrderCheckDTO>> checkPriceAndCount(PostOrderCheckReq req, String secretId, String secretKey) {
        Long timestamp = new Date().getTime();
        String sign = RezenSigUtils.genSign(secretKey, secretId, timestamp, JsonUtil.toString(req));
        RezenBaseResp<List<PostOrderCheckDTO>> resp =
                rezenClient.checkPriceAndCount(req, secretId, timestamp, sign);
        // 失败会返回正确的价格
//        if (resp.isFail()) {
//            throw new RuntimeException(resp.getRetdesc());
//        }
        return resp;
    }
}
